penCV isContinuous()连续存储的问题

您所在的位置:网站首页 opencv iscontinous penCV isContinuous()连续存储的问题

penCV isContinuous()连续存储的问题

2023-04-05 03:50| 来源: 网络整理| 查看: 265

转置:(221条消息) OpenCV isContinuous()连续存储的问题_pan_jinquan的博客-CSDN博客

 

 

OpenCV isContinuous()连续存储的问题

pan_jinquan

于 2017-11-23 20:15:19 发布

10126 收藏 18分类专栏: OpenCV 文章标签: isContinuous Mat图像连续存储 OpenCV isContinuous版权

OpenCV专栏收录该内容33 篇文章28 订阅订阅专栏OpenCV isContinuous()连续存储的问题 【尊重原创,转载请注明出处】http://blog.csdn.net/guyuealian/article/details/78614662一、OpenCV isContinuous()函数:定义:bool cv::Mat::isContinuous() const

说明: 报告矩阵是否连续。 如果矩阵元素在每行末尾连续存储而没有间隙,则方法返回true。 否则,它返回false。 显然,对于1x1或1xN矩阵总是连续的。一般 用Mat :: create创建的矩阵总是连续的。 但是,如果使用Mat :: col,Mat :: diag等提取矩阵的一部分,或者为外部分配的数据构造矩阵头,则此类矩阵可能不再具有此属性。 连续性标志存储在Mat :: flags字段中,并在构造矩阵标题时自动计算。 因此,连续性检查是一个非常快的操作,虽然理论上可以这样做:// alternative implementation of Mat::isContinuous()bool myCheckMatContinuity(const Mat& m){ //return (m.flags & Mat::CONTINUOUS_FLAG) != 0; return m.rows == 1 || m.step == m.cols*m.elemSize();//检测内存存储连续性} 这个isContinuous方法在很多OpenCV函数中都有使用。 重点在于元素操作(例如算术和逻辑操作,数学函数,alpha 混合,颜色空间变换等)不依赖于图像几何。 因此,如果所有的输入和输出数组都是连续的,那么函数可以将它们处理为非常长的单行向量。 下面的例子说明了如何实现一个alpha混合(透明混合)函数:templatevoid alphaBlendRGBA(const Mat& src1, const Mat& src2, Mat& dst){ const float alpha_scale = (float)std::numeric_limits::max(), inv_scale = 1.f/alpha_scale; CV_Assert( src1.type() == src2.type() && src1.type() == CV_MAKETYPE(DataType::depth, 4) && src1.size() == src2.size()); Size size = src1.size(); dst.create(size, src1.type()); // here is the idiom: check the arrays for continuity and, // if this is the case, // treat the arrays as 1D vectors if( src1.isContinuous() && src2.isContinuous() && dst.isContinuous() ) { size.width *= size.height; size.height = 1; } size.width *= 4; for( int i = 0; i < size.height; i++ ) { // when the arrays are continuous, // the outer loop is executed only once const T* ptr1 = src1.ptr(i); const T* ptr2 = src2.ptr(i); T* dptr = dst.ptr(i); for( int j = 0; j < size.width; j += 4 ) { float alpha = ptr1[j+3]*inv_scale, beta = ptr2[j+3]*inv_scale; dptr[j] = saturate_cast(ptr1[j]*alpha + ptr2[j]*beta); dptr[j+1] = saturate_cast(ptr1[j+1]*alpha + ptr2[j+1]*beta); dptr[j+2] = saturate_cast(ptr1[j+2]*alpha + ptr2[j+2]*beta); dptr[j+3] = saturate_cast((1 - (1-alpha)*(1-beta))*alpha_scale); } }}

这种方法虽然非常简单,但是可以将简单元素操作的性能提高10-20%,特别是如果图像相当小并且操作非常简单。 在这个函数中的另一个OpenCV习惯用法,调用目标数组的Mat :: create,除非它已经具有适当的大小和类型,否则分配目标数组。 而新分配的数组总是连续的,你仍然需要检查目标数组,因为Mat :: create并不总是分配一个新的矩阵。 用Mat存储一幅图像时,若图像在内存中是连续存储的(Mat对象的isContinuous == true),则可以将图像的数据看成是一个一维数组,而data(uchar*)成员就是指向图像数据的第一个字节的,因此可以用data指针访问图像的数据,从而加速Mat图像的访问速度。 一般经过裁剪的Mat图像,都不再连续了,如cv::Mat crop_img = src(rect);crop_img 是不连续的Mat图像,如果想转为连续的,最简单的方法,就是将不连续的crop_img 重新clone()一份给新的Mat就是连续的了,如:

Mat src = imread("D:\\OpencvTest\\B1.jpg");//原始图像是200*200 cv::imshow("src", src); printf("---src.isContinuous=%d", src.isContinuous()); printf("\n");//直接imread的Mat是连续的 cv::Rect rect(1, 1, 100, 100); cv::Mat crop_img = src(rect);//裁剪后的图像是不连续的 cv::imshow("crop_img", crop_img); printf("---crop_img.isContinuous=%d", crop_img.isContinuous()); printf("\n"); cv::Mat crop_img2; //crop_img2.create(crop_img2.size(), crop_img2.type()); crop_img2 = crop_img.clone();//重新clone()后的图像是连续的 printf("---crop_img2.isContinuous=%d", crop_img2.isContinuous()); printf("\n");运行结果:显然,裁剪后的Mat图像不再连续,而重新clone()一份后又连续了.

————————————————版权声明:本文为CSDN博主「pan_jinquan」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/guyuealian/article/details/78614662



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3